<!DOCTYPE html>
<title>HTML5 Web Workers</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<link rel="stylesheet" href = "styles.css">

<h1>HTML5 Web Workers</h1>

<p id="status">你的浏览器不支持HTML5 Web Workers.</p>


<button id="startBlurButton" disabled>模糊</button>
<button id="stopButton" disabled>停止Workers</button>
<button onclick="document.location = document.location;">重新加载</button>

<label for="workerCount">Workers数量</label>
<select id="workerCount">
    <option>1</option>
    <option selected>2</option>
    <option>4</option>
    <option>8</option>
    <option>16</option>
</select>

<div id="imageContainer"></div>
<div id="logOutput"></div>
<script>
	var imageURL = "exampe2.png";
	var image;
	var ctx;
	var workers = [];
	
	window.addEventListener("load", loadDemo, true);
	
	function loadDemo(){
		log("加载图像数据");
		if(typeof(Worker) !== "undefined"){
			 document.getElementById("status").innerHTML = "你的浏览器支持HTML5 Web Workers";

			document.getElementById("stopButton").onclick = stopBlur;
			document.getElementById("startBlurButton").onclick = startBlur;

			loadImageData(imageURL);

			document.getElementById("startBlurButton").disabled = true;
			document.getElementById("stopButton").disabled = true;
		}
	}
	
	function log(s){
		var logOutput = document.getElementById("logOutput");
		logOutput.innerHTML = s + "<br>" + logOutput.innerHTML;	
	}
	
	function loadImageData(url){
		var canvas = document.createElement('canvas');
		ctx = canvas.getContext('2d');
		image = new Image();
		image.src = url;
		
		document.getElementById("imageContainer").appendChild(canvas);
		
		image.onload = function(){
			canvas.width = image.width;
			canvas.height = image.height;
			ctx.drawImage(image, 0, 0);
			window.imgdata = ctx.getImageData(0, 0, image.width, image.height);
			
			n = ctx.crerateImageData(image.width, image.height);
			
			setRunningState(false);
			
			log("图像加载：" + image.width + "x" + image.height + "pixels");		
		}
	}
	
	function setRunningState(p){
		document.getElementById("startBlurButton").disabled = p;
		document.getElementById("stopButton").disabled = !p;
	}
	
	
	function stopBlur(){
		for(var i=0; i<worders.length; i++){
			workers[i].terminate();		
		}
		setRunningState(false);
	}
	
	function startBlur(){
		var workerCount = parseInt(document.getElementById("workerCount").value);
		var width = image.width/workerCount;
		
		for(var i=0; i<workerCount; i++){
			var worker = initWorker("blurWorker.js");
			worker.index = i;
			worker.width = width;
			workers[i] = worker;
			
			sendBlurTask(worker, i, width);
		}
		setRunningState(true);
	}
	
	function initWorker(src){
		var worker = new Worker(src);
		worker.addEventListener("message",messageHandler, true);
		worker.addEventListener("error",errorHandler, true);
		return worker;
	}
		
	function messageHandler(e) {
		var messageType = e.data.type;
		switch (messageType) {
			case ("status"):
				log(e.data.statusText);
				break;
			case ("progress"):
				var imageData = ctx.createImageData(e.data.width, e.data.height);

				for (var i = 0; i<imageData.data.length; i++) {
					var val = e.data.imageData[i];
					if (val === null || val > 255 || val < 0) {
						log("illegal value: " + val + " at " + i);
						return;
					}

					imageData.data[i] = val;
				}
				ctx.putImageData(imageData, e.data.startX, 0);

				// blur the same tile again
				sendBlurTask(e.target, e.target.index, e.target.width);
				break;
			default:
				break;
		}
	}

	function errorHandler(e) {
		log("error: " + e.message);
	}

	function sendBlurTask(worker, i, chunkWidth) {
        var chunkHeight = image.height;
        var chunkStartX = i * chunkWidth;
        var chunkStartY = 0;
        var data = ctx.getImageData(chunkStartX, chunkStartY,
                                    chunkWidth, chunkHeight).data;

        worker.postMessage({'type' : 'blur',
                            'imageData' : data,
                            'width' : chunkWidth,
                            'height' : chunkHeight,
                            'startX' : chunkStartX});
	}

	
</script>